home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH11 / PGM11_1.ASM < prev   
Encoding:
Assembly Source File  |  1996-02-11  |  10.7 KB  |  589 lines

  1. ; Pgm11_1.asm
  2. ;
  3. ; Screen Aids.
  4. ;
  5. ; This program provides some useful screen manipulation routines
  6. ; that let you do things like position the cursor, save and restore
  7. ; the contents of the display screen, clear the screen, etc.
  8. ;
  9. ; This program is not very efficient.  It was written to demonstrate
  10. ; parameter passing, use of local variables, and direct conversion of
  11. ; loops to assembly language.  There are far better ways of doing
  12. ; what this program does (running about 5-10x faster) using the 80x86
  13. ; string instructions.
  14.  
  15.  
  16.  
  17.         .xlist
  18.         include     stdlib.a
  19.         includelib    stdlib.lib
  20.         .list
  21.  
  22.         .386            ;Comment out these two statements
  23.         option    segment:use16    ; if you are not using an 80386.
  24.  
  25.  
  26. ; ScrSeg- This is the video screen's segment address.  It should be
  27. ;        B000 for mono screens and B800 for color screens.
  28.  
  29. ScrSeg        =    0B800h
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36. dseg        segment    para public 'data'
  37.  
  38. XPosn        word    ?        ;Cursor X-Coordinate (0..79)
  39. YPosn        word    ?        ;Cursor Y-Coordinate (0..24)
  40.  
  41. ; The following array holds a copy of the initial screen data.
  42.  
  43. SaveScr        word    25 dup (80 dup (?))
  44.  
  45. dseg        ends
  46.  
  47.  
  48. cseg        segment    para public 'code'
  49.         assume    cs:cseg, ds:dseg
  50.  
  51.  
  52. ; Capture-    Copies the data on the screen to the array passed
  53. ;        by reference as a parameter.
  54. ;
  55. ; procedure Capture(var ScrCopy:array[0..24,0..79] of word);
  56. ; var x,y:integer;
  57. ; begin
  58. ;
  59. ;    for y := 0 to 24 do
  60. ;        for x := 0 to 79 do
  61. ;        SCREEN[y,x] := ScrCopy[y,x];
  62. ; end;
  63. ;
  64. ;
  65. ; Activation record for Capture:
  66. ;
  67. ;    |            |
  68. ;    | Previous stk contents    |
  69. ;    -------------------------
  70. ;    |  ScrCopy Seg Adrs    |
  71. ;    --               --
  72. ;    | ScrCopy offset Adrs    |
  73. ;    -------------------------
  74. ;    | Return Adrs (near)    |
  75. ;    -------------------------
  76. ;    |      Old BP        |
  77. ;    ------------------------- <- BP
  78. ;    |  X coordinate value    |
  79. ;    -------------------------
  80. ;    |  Y coordinate value    |
  81. ;    -------------------------
  82. ;    | Registers, etc.    |
  83. ;    ------------------------- <- SP
  84.  
  85.  
  86.  
  87. ScrCopy_cap    textequ    <dword ptr [bp+4]>
  88. X_cap        textequ    <word ptr [bp-2]>
  89. Y_cap        textequ    <word ptr [bp-4]>
  90.  
  91. Capture        proc
  92.         push    bp
  93.         mov    bp, sp
  94.         sub    sp, 4            ;Allocate room for locals.
  95.  
  96.         push    es
  97.         push    ds
  98.         push    ax
  99.         push    bx
  100.         push    di
  101.  
  102.         mov    bx, ScrSeg        ;Set up pointer to SCREEN
  103.         mov    es, bx            ; memory (ScrSeg:0).
  104.  
  105.         lds    di, ScrCopy_cap        ;Get ptr to capture array.
  106.  
  107.         mov    Y_cap, 0
  108. YLoop:        mov    X_cap, 0
  109. XLoop:        mov    bx, Y_cap
  110.         imul    bx, 80            ;Screen memory is a 25x80 array
  111.         add    bx, X_cap        ; stored in row major order
  112.         add    bx, bx            ; with two bytes per element.
  113.  
  114.         mov    ax, es:[bx]        ;Read character code from screen.
  115.         mov    ds:[di][bx], ax        ;Store away into capture array.
  116.  
  117.         inc    X_Cap            ;Repeat for each character on this
  118.         cmp    X_Cap, 80        ; row of characters (each character
  119.         jb    XLoop            ; in the row is two bytes).
  120.  
  121.         inc    Y_Cap            ;Repeat for each row on the screen.
  122.         cmp    Y_Cap, 25
  123.         jb    YLoop
  124.  
  125.         pop    di
  126.         pop    bx
  127.         pop    ax
  128.         pop    ds
  129.         pop    es
  130.         mov    sp, bp
  131.         pop    bp
  132.         ret    4
  133. Capture        endp
  134.  
  135.  
  136.  
  137.  
  138.  
  139. ; Fill-        Copies array passed by reference onto the screen.
  140. ;
  141. ; procedure Fill(var ScrCopy:array[0..24,0..79] of word);
  142. ; var x,y:integer;
  143. ; begin
  144. ;
  145. ;    for y := 0 to 24 do
  146. ;        for x := 0 to 79 do
  147. ;        ScrCopy[y,x] := SCREEN[y,x];
  148. ; end;
  149. ;
  150. ;
  151. ; Activation record for Fill:
  152. ;
  153. ;    |            |
  154. ;    | Previous stk contents    |
  155. ;    -------------------------
  156. ;    |  ScrCopy Seg Adrs    |
  157. ;    --               --
  158. ;    | ScrCopy offset Adrs    |
  159. ;    -------------------------
  160. ;    | Return Adrs (near)    |
  161. ;    -------------------------
  162. ;    |      Old BP        |
  163. ;    ------------------------- <- BP
  164. ;    |  X coordinate value    |
  165. ;    -------------------------
  166. ;    |  Y coordinate value    |
  167. ;    -------------------------
  168. ;    | Registers, etc.    |
  169. ;    ------------------------- <- SP
  170.  
  171.  
  172.  
  173. ScrCopy_fill    textequ    <dword ptr [bp+4]>
  174. X_fill        textequ    <word ptr [bp-2]>
  175. Y_fill        textequ    <word ptr [bp-4]>
  176.  
  177. Fill        proc
  178.         push    bp
  179.         mov    bp, sp
  180.         sub    sp, 4
  181.  
  182.         push    es
  183.         push    ds
  184.         push    ax
  185.         push    bx
  186.         push    di
  187.  
  188.         mov    bx, ScrSeg        ;Set up pointer to SCREEN
  189.         mov    es, bx            ; memory (ScrSeg:0).
  190.  
  191.         lds    di, ScrCopy_fill    ;Get ptr to data array.
  192.  
  193.         mov    Y_Fill, 0
  194. YLoop:        mov    X_Fill, 0
  195. XLoop:        mov    bx, Y_Fill
  196.         imul    bx, 80            ;Screen memory is a 25x80 array
  197.         add    bx, X_Fill        ; stored in row major order
  198.         add    bx, bx            ; with two bytes per element.
  199.  
  200.         mov    ax, ds:[di][bx]        ;Store away into capture array.
  201.         mov    es:[bx], ax        ;Read character code from screen.
  202.  
  203.         inc    X_Fill            ;Repeat for each character on this
  204.         cmp    X_Fill, 80        ; row of characters (each character
  205.         jb    XLoop            ; in the row is two bytes).
  206.  
  207.         inc    Y_Fill            ;Repeat for each row on the screen.
  208.         cmp    Y_Fill, 25
  209.         jb    YLoop
  210.  
  211.         pop    di
  212.         pop    bx
  213.         pop    ax
  214.         pop    ds
  215.         pop    es
  216.         mov    sp, bp
  217.         pop    bp
  218.         ret    4
  219. Fill        endp
  220.  
  221.  
  222.  
  223.  
  224.  
  225. ; Scroll_up-    Scrolls the screen up on line.  It does this by copying the second line
  226. ;        to the first, the third line to the second, the fourth line to the third,
  227. ;        etc.
  228. ;
  229. ; procedure Scroll_up;
  230. ; var x,y:integer;
  231. ; begin
  232. ;    for y := 1 to 24 do
  233. ;        for x := 0 to 79 do
  234. ;        SCREEN[Y-1,X] := SCREEN[Y,X];
  235. ; end;
  236. ;
  237. ; Activation record for Scroll_up:
  238. ;
  239. ;    |            |
  240. ;    | Previous stk contents    |
  241. ;    -------------------------
  242. ;    | Return Adrs (near)    |
  243. ;    -------------------------
  244. ;    |      Old BP        |
  245. ;    ------------------------- <- BP
  246. ;    |  X coordinate value    |
  247. ;    -------------------------
  248. ;    |  Y coordinate value    |
  249. ;    -------------------------
  250. ;    | Registers, etc.    |
  251. ;    ------------------------- <- SP
  252.  
  253.  
  254.  
  255. X_su        textequ    <word ptr [bp-2]>
  256. Y_su        textequ    <word ptr [bp-4]>
  257.  
  258. Scroll_up    proc
  259.         push    bp
  260.         mov    bp, sp
  261.         sub    sp, 4            ;Make room for X, Y.
  262.  
  263.         push    ds
  264.         push    ax
  265.         push    bx
  266.  
  267.         mov    ax, ScrSeg
  268.         mov    ds, ax
  269.         mov    Y_su, 0
  270. su_Loop1:    mov    X_su, 0
  271.  
  272. su_Loop2:    mov    bx, Y_su        ;Compute index into screen
  273.         imul    bx, 80            ; array.
  274.         add    bx, X_su
  275.         add    bx, bx            ;Remember, this is a word array.
  276.     
  277.         mov    ax, ds:[bx+160]        ;Fetch word from source line.
  278.         mov    ds:[bx], ax        ;Store into dest line.
  279.  
  280.         inc    X_su
  281.         cmp    X_su, 80
  282.         jb    su_Loop2
  283.  
  284.         inc    Y_su
  285.         cmp    Y_su, 80
  286.         jb    su_Loop1
  287.  
  288.         pop    bx
  289.         pop    ax
  290.         pop    ds
  291.         mov    sp, bp
  292.         pop    bp
  293.         ret
  294. Scroll_up    endp
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301. ; Scroll_dn-    Scrolls the screen down one line.  It does this by copying the 24th line
  302. ;        to the 25th, the 23rd line to the 24th, the 22nd line to the 23rd,
  303. ;        etc.
  304. ;
  305. ; procedure Scroll_dn;
  306. ; var x,y:integer;
  307. ; begin
  308. ;    for y := 23 downto 0 do
  309. ;        for x := 0 to 79 do
  310. ;        SCREEN[Y+1,X] := SCREEN[Y,X];
  311. ; end;
  312. ;
  313. ; Activation record for Scroll_dn:
  314. ;
  315. ;    |            |
  316. ;    | Previous stk contents    |
  317. ;    -------------------------
  318. ;    | Return Adrs (near)    |
  319. ;    -------------------------
  320. ;    |      Old BP        |
  321. ;    ------------------------- <- BP
  322. ;    |  X coordinate value    |
  323. ;    -------------------------
  324. ;    |  Y coordinate value    |
  325. ;    -------------------------
  326. ;    | Registers, etc.    |
  327. ;    ------------------------- <- SP
  328.  
  329.  
  330. X_sd        textequ    <word ptr [bp-2]>
  331. Y_sd        textequ    <word ptr [bp-4]>
  332.  
  333. Scroll_dn    proc
  334.         push    bp
  335.         mov    bp, sp
  336.         sub    sp, 4            ;Make room for X, Y.
  337.  
  338.         push    ds
  339.         push    ax
  340.         push    bx
  341.  
  342.         mov    ax, ScrSeg
  343.         mov    ds, ax
  344.         mov    Y_sd, 23
  345. sd_Loop1:    mov    X_sd, 0
  346.  
  347. sd_Loop2:    mov    bx, Y_sd        ;Compute index into screen
  348.         imul    bx, 80            ; array.
  349.         add    bx, X_sd
  350.         add    bx, bx            ;Remember, this is a word array.
  351.     
  352.         mov    ax, ds:[bx]        ;Fetch word from source line.
  353.         mov    ds:[bx+160], ax        ;Store into dest line.
  354.  
  355.         inc    X_sd
  356.         cmp    X_sd, 80
  357.         jb    sd_Loop2
  358.  
  359.         dec    Y_sd
  360.         cmp    Y_sd, 0
  361.         jge    sd_Loop1
  362.  
  363.         pop    bx
  364.         pop    ax
  365.         pop    ds
  366.         mov    sp, bp
  367.         pop    bp
  368.         ret
  369. Scroll_dn    endp
  370.  
  371.  
  372.  
  373.  
  374. ; GotoXY-    Positions the cursor at the specified X, Y coordinate.
  375. ;
  376. ; procedure gotoxy(x,y:integer);
  377. ; begin
  378. ;    BIOS(posnCursor,x,y);
  379. ; end;
  380. ;
  381. ; Activation record for GotoXY
  382. ;
  383. ;    |            |
  384. ;    | Previous stk contents    |
  385. ;    -------------------------
  386. ;    |  X coordinate value    |
  387. ;    -------------------------
  388. ;    |  Y coordinate value    |
  389. ;    -------------------------
  390. ;    | Return Adrs (near)    |
  391. ;    -------------------------
  392. ;    |      Old BP        |
  393. ;    ------------------------- <- BP
  394. ;    | Registers, etc.    |
  395. ;    ------------------------- <- SP
  396.  
  397.  
  398. X_gxy        textequ    <byte ptr [bp+6]>
  399. Y_gxy        textequ    <byte ptr [bp+4]>
  400.  
  401. GotoXY        proc
  402.         push    bp
  403.         mov    bp, sp
  404.         push    ax
  405.         push    bx
  406.         push    dx
  407.  
  408.         mov    ah, 2            ;Magic BIOS value for gotoxy.
  409.         mov    bh, 0            ;Display page zero.
  410.         mov    dh, Y_gxy        ;Set up BIOS (X,Y) parameters.
  411.         mov    dl, X_gxy
  412.         int    10h            ;Make the BIOS call.
  413.  
  414.         pop    dx
  415.         pop    bx
  416.         pop    ax
  417.         mov    sp, bp
  418.         pop    bp
  419.         ret    4
  420. GotoXY        endp
  421.  
  422.  
  423.  
  424. ; GetX-        Returns cursor X-Coordinate in the AX register.
  425.  
  426. GetX        proc
  427.         push    bx
  428.         push    cx
  429.         push    dx
  430.  
  431.         mov    ah, 3        ;Read X, Y coordinates from
  432.         mov    bh, 0        ; BIOS
  433.         int    10h
  434.  
  435.         mov    al, dl        ;Return X coordinate in AX.
  436.         mov    ah, 0
  437.  
  438.         pop    dx
  439.         pop    cx
  440.         pop    bx
  441.         ret
  442. GetX        endp
  443.  
  444.  
  445.  
  446. ; GetY-        Returns cursor Y-Coordinate in the AX register.
  447.  
  448. GetY        proc
  449.         push    bx
  450.         push    cx
  451.         push    dx
  452.  
  453.         mov    ah, 3
  454.         mov    bh, 0
  455.         int    10h
  456.  
  457.         mov    al, dh        ;Return Y Coordinate in AX.
  458.         mov    ah, 0
  459.  
  460.         pop    dx
  461.         pop    cx
  462.         pop    bx
  463.         ret
  464. GetY        endp
  465.  
  466.  
  467.  
  468. ; ClearScrn-    Clears the screen and positions the cursor at (0,0).
  469. ;
  470. ; procedure ClearScrn;
  471. ; begin
  472. ;    BIOS(Initialize)
  473. ; end;
  474.  
  475. ClearScrn    proc
  476.         push    ax
  477.         push    bx
  478.         push    cx
  479.         push    dx
  480.  
  481.         mov    ah, 6        ;Magic BIOS number.
  482.         mov    al, 0        ;Clear entire screen.
  483.         mov    bh, 07        ;Clear with black spaces.
  484.         mov    cx, 0000    ;Upper left corner is (0,0)
  485.         mov    dl, 79        ;Lower X-coordinate
  486.         mov    dh, 24        ;Lower Y-coordinate
  487.         int    10h        ;Make the BIOS call.
  488.  
  489.         push    0        ;Position the cursor to (0,0)
  490.         push    0        ; after the call.
  491.         call    GotoXY
  492.  
  493.         pop    dx
  494.         pop    cx
  495.         pop    bx
  496.         pop    ax
  497.         ret
  498. ClearScrn    endp
  499.  
  500.  
  501.  
  502.  
  503. ; A short main program to test out the above:
  504.  
  505. Main        proc
  506.         mov    ax, dseg
  507.         mov    ds, ax
  508.         mov    es, ax
  509.         meminit
  510.  
  511. ; Save the screen as it looks when this program is run.
  512.  
  513.         push    seg SaveScr
  514.         push    offset SaveScr
  515.         call    Capture
  516.  
  517.         call    GetX
  518.         mov    XPosn, ax
  519.  
  520.         call    GetY
  521.         mov    YPosn, ax
  522.  
  523.  
  524. ; Clear the screen to prepare for our stuff.
  525.  
  526.         call    ClearScrn
  527.  
  528. ; Position the cursor in the middle of the screen and print some stuff.
  529.  
  530.         push    30        ;X value
  531.         push    10        ;Y value
  532.         call    GotoXY
  533.  
  534.         print
  535.         byte    "Screen Manipulatation Demo",0
  536.  
  537.         push    30
  538.         push    11
  539.         call    GotoXY
  540.  
  541.         print
  542.         byte    "Press any key to continue",0
  543.  
  544.         getc
  545.  
  546.  
  547. ; Scroll the screen up two lines
  548.  
  549.         call    Scroll_up
  550.         call    Scroll_up
  551.         getc
  552.  
  553. ;Scroll the screen down four lines:
  554.  
  555.         call    Scroll_dn
  556.         call    Scroll_dn
  557.         call    Scroll_dn
  558.         call    Scroll_dn
  559.         getc
  560.  
  561.  
  562.  
  563.  
  564. ; Restore the screen to what it looked like prior to this call.
  565.  
  566.         push    seg SaveScr
  567.         push    offset SaveScr
  568.         call    Fill
  569.  
  570.         push    XPosn
  571.         push    YPosn
  572.         call    GotoXY
  573.  
  574.  
  575.  
  576. Quit:        ExitPgm            ;DOS macro to quit program.
  577. Main        endp
  578.  
  579. cseg        ends
  580.  
  581. sseg        segment    para stack 'stack'
  582. stk        byte    1024 dup ("stack   ")
  583. sseg        ends
  584.  
  585. zzzzzzseg    segment    para public 'zzzzzz'
  586. LastBytes    byte    16 dup (?)
  587. zzzzzzseg    ends
  588.         end    Main
  589.